/**
 ***********************************************************************************************************
 * 
 ***********************************************************************************************************
 * @file RBMathVector.h
 ***********************************************************************************************************/

#ifndef __RBMATHVECTOR_H__
#define __RBMATHVECTOR_H__

#ifdef  HEADER_ONCE
#pragma HEADER_ONCE
#endif

#ifdef  HEADER_MSG
#pragma HEADER_MSG(RBMathVector.h)
#endif

/***********************************************************************************************************
 * Includes
 ***********************************************************************************************************/
#include <RBMain/RBVector.h>
#include <RBMain/RBMatrix.h>
#include <RBMain/RBTransform.h>
#include <RBMain/RBHandle.h>

/***********************************************************************************************************
 * Forward declarations
 ***********************************************************************************************************/
class RBPlane;
RBDeclareHandle(RBBVolume);

/***********************************************************************************************************
 * Classes
 ***********************************************************************************************************/

namespace RBMath
{
    //////////////////////////////////////////////////////////////////////////
    // Vector specific operations
    //////////////////////////////////////////////////////////////////////////
    float3                 Cross    (const float3& a, const float3& b);

    //////////////////////////////////////////////////////////////////////////
    // Matrix operations
    //////////////////////////////////////////////////////////////////////////
    float4x4                Build   (const float3& Translate, const float3x3& Rotate, const float3& scale);
    float4x4                Build   (const RBTransform& trans);

    // Transformations
    template<uint8 dim, class T> T MultVector(const T& left, const T& right);
    template<uint8 dim, class T> T MultMatrix(const T& left, const T& right);
    template<uint8 dim, class T> T AddMatrix(const T& left, const T& right);
    template<uint8 dim, class T> T SubMatrix(const T& left, const T& right);
    template<uint8 dim, class T> T ScaleMatrix(const T& mat, float scale);
    template<uint8 dim, class T> T TransposeMatrix(const T& mat);
    template<uint8 dim, class Matrix, class Vector> Vector Transform(const Matrix& mat, const Vector& point);

    // Accessors
    template<uint8 dim, class Matrix, class Vector> void GetCol(const Matrix& mat, Vector& point, uint8 uiCol);
    template<uint8 dim, class Matrix, class Vector> void SetCol(Matrix& mat, const Vector& point, uint8 uiCol);
    template<uint8 dim, class Matrix, class Vector> void GetRow(const Matrix& mat, Vector& point, uint8 uiRow);
    template<uint8 dim, class Matrix, class Vector> void SetRow(Matrix& mat, const Vector& point, uint8 uiRow);

    //////////////////////////////////////////////////////////////////////////

    float4x4                InvertMatrix(float4x4 mat);

    namespace Intersect
    {
        void                BoxesVsFrustum(int8* result, const class RBPlane* frusta, RBBVolumeHandle* boxes, uint32 count);
    }

    float3 ProjectPointOnPlane(const RBPlane& plane, float3 point);

    void   ComputeFrustumPlanes(RBPlane* planes, const float4x4& viewProjection);

};

#include "RBMathVector.inl"

/***********************************************************************************************************/

#endif // __RBMATHVECTOR_H__
